#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
交互式决策支持系统

根据优化方案实现的交互式决策支持：
1. 实时决策引擎 - 提供实时决策支持
2. 场景模拟器 - 支持假设分析
3. 敏感性分析器 - 分析参数敏感性
4. 决策建议生成器 - 生成个性化建议
"""

import logging
import numpy as np
import pandas as pd
from typing import Dict, List, Any, Optional, Tuple, Union, Callable
from dataclasses import dataclass, field
from enum import Enum
import json
from datetime import datetime, timedelta
from collections import defaultdict, deque
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
import copy


class DecisionUrgency(Enum):
    """决策紧急程度"""
    LOW = "低"
    MEDIUM = "中等"
    HIGH = "高"
    CRITICAL = "紧急"


class AnalysisType(Enum):
    """分析类型"""
    WHAT_IF = "假设分析"
    SENSITIVITY = "敏感性分析"
    SCENARIO_COMPARISON = "情景对比"
    OPTIMIZATION = "优化分析"
    RISK_ANALYSIS = "风险分析"
    TREND_ANALYSIS = "趋势分析"


class RecommendationConfidence(Enum):
    """建议置信度"""
    LOW = "低置信度"
    MEDIUM = "中等置信度"
    HIGH = "高置信度"
    VERY_HIGH = "极高置信度"


@dataclass
class DecisionContext:
    """决策上下文"""
    user_id: str
    session_id: str
    problem_type: str
    urgency: DecisionUrgency
    constraints: Dict[str, Any] = field(default_factory=dict)
    preferences: Dict[str, Any] = field(default_factory=dict)
    historical_decisions: List[Dict[str, Any]] = field(default_factory=list)
    current_state: Dict[str, Any] = field(default_factory=dict)
    objectives: List[str] = field(default_factory=list)
    stakeholders: List[str] = field(default_factory=list)
    time_horizon: str = "短期"
    budget_constraints: float = 0.0
    risk_tolerance: float = 0.5  # 0-1, 0为风险厌恶，1为风险偏好


@dataclass
class ScenarioParameters:
    """情景参数"""
    scenario_id: str
    name: str
    description: str
    parameters: Dict[str, float]
    probability: float = 1.0
    is_baseline: bool = False
    created_at: datetime = field(default_factory=datetime.now)
    tags: List[str] = field(default_factory=list)


@dataclass
class SensitivityResult:
    """敏感性分析结果"""
    parameter_name: str
    base_value: float
    sensitivity_coefficient: float
    impact_range: Tuple[float, float]
    critical_threshold: Optional[float] = None
    elasticity: float = 0.0
    confidence_interval: Tuple[float, float] = (0.0, 0.0)


@dataclass
class DecisionRecommendation:
    """决策建议"""
    recommendation_id: str
    title: str
    description: str
    recommended_action: str
    confidence: RecommendationConfidence
    expected_outcome: Dict[str, float]
    implementation_steps: List[str] = field(default_factory=list)
    required_resources: List[str] = field(default_factory=list)
    timeline: str = ""
    risks: List[str] = field(default_factory=list)
    alternatives: List[str] = field(default_factory=list)
    success_probability: float = 0.0
    cost_benefit_ratio: float = 0.0
    stakeholder_impact: Dict[str, str] = field(default_factory=dict)


@dataclass
class InteractiveSession:
    """交互式会话"""
    session_id: str
    user_id: str
    start_time: datetime
    last_activity: datetime
    context: DecisionContext
    analysis_history: List[Dict[str, Any]] = field(default_factory=list)
    scenarios: Dict[str, ScenarioParameters] = field(default_factory=dict)
    recommendations: List[DecisionRecommendation] = field(default_factory=list)
    user_feedback: List[Dict[str, Any]] = field(default_factory=list)
    is_active: bool = True


class RealTimeDecisionEngine:
    """
    实时决策引擎
    """
    
    def __init__(self, max_workers: int = 4):
        self.logger = logging.getLogger(__name__)
        self.executor = ThreadPoolExecutor(max_workers=max_workers)
        self.active_sessions = {}
        self.decision_cache = {}
        self.performance_metrics = defaultdict(list)
        self._lock = threading.Lock()
    
    def create_session(self, user_id: str, context: DecisionContext) -> str:
        """
        创建决策会话
        
        Args:
            user_id: 用户ID
            context: 决策上下文
            
        Returns:
            str: 会话ID
        """
        session_id = f"{user_id}_{int(time.time())}"
        
        session = InteractiveSession(
            session_id=session_id,
            user_id=user_id,
            start_time=datetime.now(),
            last_activity=datetime.now(),
            context=context
        )
        
        with self._lock:
            self.active_sessions[session_id] = session
        
        self.logger.info(f"创建决策会话: {session_id}")
        return session_id
    
    def get_real_time_recommendation(self, session_id: str, 
                                   current_data: Dict[str, Any],
                                   analysis_type: AnalysisType = AnalysisType.OPTIMIZATION) -> DecisionRecommendation:
        """
        获取实时决策建议
        
        Args:
            session_id: 会话ID
            current_data: 当前数据
            analysis_type: 分析类型
            
        Returns:
            DecisionRecommendation: 决策建议
        """
        try:
            session = self.active_sessions.get(session_id)
            if not session:
                raise ValueError(f"会话不存在: {session_id}")
            
            # 更新会话活动时间
            session.last_activity = datetime.now()
            
            # 检查缓存
            cache_key = self._generate_cache_key(session_id, current_data, analysis_type)
            if cache_key in self.decision_cache:
                cached_result = self.decision_cache[cache_key]
                if self._is_cache_valid(cached_result):
                    return cached_result['recommendation']
            
            # 生成实时建议
            start_time = time.time()
            recommendation = self._generate_recommendation(
                session, current_data, analysis_type
            )
            processing_time = time.time() - start_time
            
            # 缓存结果
            self.decision_cache[cache_key] = {
                'recommendation': recommendation,
                'timestamp': datetime.now(),
                'processing_time': processing_time
            }
            
            # 记录性能指标
            self.performance_metrics['processing_time'].append(processing_time)
            self.performance_metrics['cache_hits'].append(0)  # 新计算
            
            # 更新会话
            session.recommendations.append(recommendation)
            session.analysis_history.append({
                'timestamp': datetime.now(),
                'analysis_type': analysis_type.value,
                'data': current_data,
                'recommendation_id': recommendation.recommendation_id
            })
            
            return recommendation
            
        except Exception as e:
            self.logger.error(f"实时决策建议生成失败: {e}")
            return self._create_fallback_recommendation(session_id, str(e))
    
    def _generate_recommendation(self, session: InteractiveSession,
                               current_data: Dict[str, Any],
                               analysis_type: AnalysisType) -> DecisionRecommendation:
        """
        生成决策建议
        """
        context = session.context
        
        # 根据分析类型选择不同的推荐策略
        if analysis_type == AnalysisType.OPTIMIZATION:
            return self._generate_optimization_recommendation(context, current_data)
        elif analysis_type == AnalysisType.RISK_ANALYSIS:
            return self._generate_risk_based_recommendation(context, current_data)
        elif analysis_type == AnalysisType.SCENARIO_COMPARISON:
            return self._generate_scenario_recommendation(context, current_data, session.scenarios)
        else:
            return self._generate_general_recommendation(context, current_data)
    
    def _generate_optimization_recommendation(self, context: DecisionContext,
                                            current_data: Dict[str, Any]) -> DecisionRecommendation:
        """
        生成优化建议
        """
        # 分析当前状态和目标
        objectives = current_data.get('objectives', {})
        constraints = current_data.get('constraints', {})
        
        # 计算最优解
        best_objective = max(objectives.values()) if objectives else 0
        best_option = max(objectives.items(), key=lambda x: x[1])[0] if objectives else "默认选项"
        
        # 评估置信度
        confidence = self._calculate_confidence(context, current_data)
        
        # 计算期望结果
        expected_outcome = {
            'profit': best_objective,
            'risk_level': context.risk_tolerance,
            'implementation_time': self._estimate_implementation_time(context)
        }
        
        return DecisionRecommendation(
            recommendation_id=f"opt_{int(time.time())}",
            title="优化决策建议",
            description=f"基于当前数据分析，建议选择{best_option}方案",
            recommended_action=f"实施{best_option}方案",
            confidence=confidence,
            expected_outcome=expected_outcome,
            implementation_steps=[
                "详细评估当前方案",
                "制定实施计划",
                "分配必要资源",
                "开始执行",
                "监控进展"
            ],
            required_resources=["项目团队", "预算", "技术支持"],
            timeline=self._estimate_timeline(context),
            risks=self._identify_risks(context, current_data),
            success_probability=min(0.9, confidence.value * 0.25 + 0.1),
            cost_benefit_ratio=best_objective / max(context.budget_constraints, 1)
        )
    
    def _generate_risk_based_recommendation(self, context: DecisionContext,
                                          current_data: Dict[str, Any]) -> DecisionRecommendation:
        """
        生成基于风险的建议
        """
        risk_factors = current_data.get('risks', {})
        risk_tolerance = context.risk_tolerance
        
        # 评估风险等级
        total_risk = sum(risk_factors.values()) if risk_factors else 0.3
        
        if total_risk > risk_tolerance:
            action = "采取风险缓解措施"
            description = f"当前风险水平({total_risk:.2f})超过您的风险承受能力({risk_tolerance:.2f})"
        else:
            action = "继续当前策略"
            description = f"当前风险水平({total_risk:.2f})在可接受范围内"
        
        confidence = RecommendationConfidence.HIGH if abs(total_risk - risk_tolerance) > 0.2 else RecommendationConfidence.MEDIUM
        
        return DecisionRecommendation(
            recommendation_id=f"risk_{int(time.time())}",
            title="风险管理建议",
            description=description,
            recommended_action=action,
            confidence=confidence,
            expected_outcome={
                'risk_reduction': max(0, total_risk - risk_tolerance),
                'cost': context.budget_constraints * 0.1
            },
            risks=list(risk_factors.keys()),
            timeline="1-3个月"
        )
    
    def _generate_scenario_recommendation(self, context: DecisionContext,
                                        current_data: Dict[str, Any],
                                        scenarios: Dict[str, ScenarioParameters]) -> DecisionRecommendation:
        """
        生成情景对比建议
        """
        if not scenarios:
            return self._generate_general_recommendation(context, current_data)
        
        # 评估各情景
        scenario_scores = {}
        for scenario_id, scenario in scenarios.items():
            score = self._evaluate_scenario(scenario, context, current_data)
            scenario_scores[scenario_id] = score
        
        # 选择最佳情景
        best_scenario_id = max(scenario_scores.items(), key=lambda x: x[1])[0]
        best_scenario = scenarios[best_scenario_id]
        
        return DecisionRecommendation(
            recommendation_id=f"scenario_{int(time.time())}",
            title="情景选择建议",
            description=f"基于情景对比分析，建议采用{best_scenario.name}方案",
            recommended_action=f"实施{best_scenario.name}情景",
            confidence=RecommendationConfidence.HIGH,
            expected_outcome={
                'scenario_score': scenario_scores[best_scenario_id],
                'probability': best_scenario.probability
            },
            alternatives=[s.name for s_id, s in scenarios.items() if s_id != best_scenario_id][:3]
        )
    
    def _generate_general_recommendation(self, context: DecisionContext,
                                       current_data: Dict[str, Any]) -> DecisionRecommendation:
        """
        生成通用建议
        """
        return DecisionRecommendation(
            recommendation_id=f"general_{int(time.time())}",
            title="通用决策建议",
            description="基于当前信息的综合分析建议",
            recommended_action="继续收集信息并监控关键指标",
            confidence=RecommendationConfidence.MEDIUM,
            expected_outcome={'status': '稳定'},
            implementation_steps=[
                "收集更多数据",
                "分析关键指标",
                "制定详细计划",
                "开始实施"
            ]
        )
    
    def _calculate_confidence(self, context: DecisionContext, current_data: Dict[str, Any]) -> RecommendationConfidence:
        """
        计算建议置信度
        """
        # 基于数据完整性、历史决策、约束条件等计算置信度
        data_completeness = len(current_data) / 10  # 假设10个字段为完整
        historical_accuracy = len(context.historical_decisions) / 20  # 历史决策数量
        constraint_clarity = len(context.constraints) / 5  # 约束条件明确性
        
        confidence_score = (data_completeness + historical_accuracy + constraint_clarity) / 3
        
        if confidence_score > 0.8:
            return RecommendationConfidence.VERY_HIGH
        elif confidence_score > 0.6:
            return RecommendationConfidence.HIGH
        elif confidence_score > 0.4:
            return RecommendationConfidence.MEDIUM
        else:
            return RecommendationConfidence.LOW
    
    def _estimate_implementation_time(self, context: DecisionContext) -> float:
        """
        估算实施时间（天）
        """
        base_time = 30  # 基础30天
        
        # 根据紧急程度调整
        urgency_multiplier = {
            DecisionUrgency.CRITICAL: 0.3,
            DecisionUrgency.HIGH: 0.5,
            DecisionUrgency.MEDIUM: 1.0,
            DecisionUrgency.LOW: 1.5
        }
        
        # 根据复杂度调整
        complexity_factor = len(context.constraints) * 0.1 + len(context.objectives) * 0.05
        
        return base_time * urgency_multiplier[context.urgency] * (1 + complexity_factor)
    
    def _estimate_timeline(self, context: DecisionContext) -> str:
        """
        估算时间线
        """
        days = self._estimate_implementation_time(context)
        
        if days <= 7:
            return "1周内"
        elif days <= 30:
            return "1个月内"
        elif days <= 90:
            return "3个月内"
        else:
            return "3个月以上"
    
    def _identify_risks(self, context: DecisionContext, current_data: Dict[str, Any]) -> List[str]:
        """
        识别风险
        """
        risks = []
        
        # 基于预算约束
        if context.budget_constraints > 0:
            estimated_cost = current_data.get('estimated_cost', 0)
            if estimated_cost > context.budget_constraints * 0.8:
                risks.append("预算超支风险")
        
        # 基于时间约束
        if context.urgency in [DecisionUrgency.HIGH, DecisionUrgency.CRITICAL]:
            risks.append("时间压力风险")
        
        # 基于复杂度
        if len(context.constraints) > 5:
            risks.append("实施复杂度风险")
        
        # 基于风险承受能力
        if context.risk_tolerance < 0.3:
            risks.append("风险厌恶约束")
        
        return risks
    
    def _evaluate_scenario(self, scenario: ScenarioParameters, 
                          context: DecisionContext, 
                          current_data: Dict[str, Any]) -> float:
        """
        评估情景得分
        """
        # 基础得分
        base_score = scenario.probability
        
        # 参数匹配度
        parameter_match = 0
        for param, value in scenario.parameters.items():
            if param in current_data:
                # 计算参数匹配度
                current_value = current_data[param]
                if isinstance(current_value, (int, float)) and isinstance(value, (int, float)):
                    match = 1 - abs(current_value - value) / max(abs(current_value), abs(value), 1)
                    parameter_match += max(0, match)
        
        if scenario.parameters:
            parameter_match /= len(scenario.parameters)
        
        # 风险匹配度
        risk_match = 1 - abs(context.risk_tolerance - 0.5)  # 假设情景风险为中等
        
        return base_score * 0.4 + parameter_match * 0.4 + risk_match * 0.2
    
    def _generate_cache_key(self, session_id: str, current_data: Dict[str, Any], 
                           analysis_type: AnalysisType) -> str:
        """
        生成缓存键
        """
        data_hash = hash(json.dumps(current_data, sort_keys=True, default=str))
        return f"{session_id}_{analysis_type.value}_{data_hash}"
    
    def _is_cache_valid(self, cached_result: Dict[str, Any], max_age_minutes: int = 5) -> bool:
        """
        检查缓存是否有效
        """
        timestamp = cached_result['timestamp']
        age = datetime.now() - timestamp
        return age.total_seconds() < max_age_minutes * 60
    
    def _create_fallback_recommendation(self, session_id: str, error_message: str) -> DecisionRecommendation:
        """
        创建备用建议
        """
        return DecisionRecommendation(
            recommendation_id=f"fallback_{int(time.time())}",
            title="系统建议",
            description=f"由于技术问题({error_message})，建议暂缓决策并寻求专家意见",
            recommended_action="暂缓决策，收集更多信息",
            confidence=RecommendationConfidence.LOW,
            expected_outcome={'status': '待定'},
            risks=["信息不足", "系统错误"]
        )
    
    def update_user_feedback(self, session_id: str, recommendation_id: str, 
                           feedback: Dict[str, Any]):
        """
        更新用户反馈
        
        Args:
            session_id: 会话ID
            recommendation_id: 建议ID
            feedback: 用户反馈
        """
        session = self.active_sessions.get(session_id)
        if session:
            session.user_feedback.append({
                'timestamp': datetime.now(),
                'recommendation_id': recommendation_id,
                'feedback': feedback
            })
            self.logger.info(f"收到用户反馈: {session_id}, {recommendation_id}")
    
    def close_session(self, session_id: str):
        """
        关闭会话
        
        Args:
            session_id: 会话ID
        """
        with self._lock:
            if session_id in self.active_sessions:
                self.active_sessions[session_id].is_active = False
                del self.active_sessions[session_id]
                self.logger.info(f"关闭决策会话: {session_id}")
    
    def get_performance_metrics(self) -> Dict[str, Any]:
        """
        获取性能指标
        """
        return {
            'active_sessions': len(self.active_sessions),
            'avg_processing_time': np.mean(self.performance_metrics['processing_time']) if self.performance_metrics['processing_time'] else 0,
            'cache_hit_rate': np.mean(self.performance_metrics['cache_hits']) if self.performance_metrics['cache_hits'] else 0,
            'total_recommendations': sum(len(s.recommendations) for s in self.active_sessions.values())
        }


class ScenarioSimulator:
    """
    场景模拟器
    """
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.simulation_cache = {}
    
    def create_scenario(self, name: str, description: str, 
                       parameters: Dict[str, float],
                       probability: float = 1.0,
                       tags: List[str] = None) -> ScenarioParameters:
        """
        创建情景
        
        Args:
            name: 情景名称
            description: 情景描述
            parameters: 参数设置
            probability: 发生概率
            tags: 标签
            
        Returns:
            ScenarioParameters: 情景参数
        """
        scenario_id = f"scenario_{int(time.time())}_{hash(name)}"
        
        return ScenarioParameters(
            scenario_id=scenario_id,
            name=name,
            description=description,
            parameters=parameters,
            probability=probability,
            tags=tags or []
        )
    
    def run_what_if_analysis(self, base_scenario: ScenarioParameters,
                           parameter_changes: Dict[str, float],
                           objective_function: Callable[[Dict[str, float]], float]) -> Dict[str, Any]:
        """
        运行假设分析
        
        Args:
            base_scenario: 基础情景
            parameter_changes: 参数变化
            objective_function: 目标函数
            
        Returns:
            Dict[str, Any]: 分析结果
        """
        try:
            # 创建新情景
            new_parameters = base_scenario.parameters.copy()
            new_parameters.update(parameter_changes)
            
            # 计算基础结果
            base_result = objective_function(base_scenario.parameters)
            
            # 计算变化后结果
            new_result = objective_function(new_parameters)
            
            # 计算影响
            absolute_change = new_result - base_result
            relative_change = (absolute_change / base_result * 100) if base_result != 0 else 0
            
            return {
                'base_result': base_result,
                'new_result': new_result,
                'absolute_change': absolute_change,
                'relative_change': relative_change,
                'parameter_changes': parameter_changes,
                'impact_analysis': self._analyze_parameter_impacts(
                    base_scenario.parameters, new_parameters, base_result, new_result
                )
            }
            
        except Exception as e:
            self.logger.error(f"假设分析失败: {e}")
            return {'error': str(e)}
    
    def run_monte_carlo_simulation(self, scenario: ScenarioParameters,
                                 parameter_distributions: Dict[str, Dict[str, float]],
                                 objective_function: Callable[[Dict[str, float]], float],
                                 num_simulations: int = 1000) -> Dict[str, Any]:
        """
        运行蒙特卡洛模拟
        
        Args:
            scenario: 基础情景
            parameter_distributions: 参数分布 {param: {'mean': x, 'std': y}}
            objective_function: 目标函数
            num_simulations: 模拟次数
            
        Returns:
            Dict[str, Any]: 模拟结果
        """
        try:
            results = []
            parameter_samples = defaultdict(list)
            
            for _ in range(num_simulations):
                # 生成随机参数
                sim_parameters = scenario.parameters.copy()
                
                for param, dist in parameter_distributions.items():
                    if param in sim_parameters:
                        # 假设正态分布
                        random_value = np.random.normal(dist['mean'], dist['std'])
                        sim_parameters[param] = random_value
                        parameter_samples[param].append(random_value)
                
                # 计算目标函数值
                result = objective_function(sim_parameters)
                results.append(result)
            
            # 统计分析
            results_array = np.array(results)
            
            return {
                'num_simulations': num_simulations,
                'mean': np.mean(results_array),
                'std': np.std(results_array),
                'min': np.min(results_array),
                'max': np.max(results_array),
                'percentiles': {
                    '5%': np.percentile(results_array, 5),
                    '25%': np.percentile(results_array, 25),
                    '50%': np.percentile(results_array, 50),
                    '75%': np.percentile(results_array, 75),
                    '95%': np.percentile(results_array, 95)
                },
                'confidence_interval_95': (
                    np.percentile(results_array, 2.5),
                    np.percentile(results_array, 97.5)
                ),
                'parameter_correlations': self._calculate_correlations(
                    parameter_samples, results
                ),
                'risk_metrics': {
                    'var_95': np.percentile(results_array, 5),  # Value at Risk
                    'cvar_95': np.mean(results_array[results_array <= np.percentile(results_array, 5)]),  # Conditional VaR
                    'probability_of_loss': np.mean(results_array < 0) if np.any(results_array < 0) else 0
                }
            }
            
        except Exception as e:
            self.logger.error(f"蒙特卡洛模拟失败: {e}")
            return {'error': str(e)}
    
    def compare_scenarios(self, scenarios: List[ScenarioParameters],
                         objective_function: Callable[[Dict[str, float]], float],
                         criteria: List[str] = None) -> Dict[str, Any]:
        """
        比较多个情景
        
        Args:
            scenarios: 情景列表
            objective_function: 目标函数
            criteria: 比较标准
            
        Returns:
            Dict[str, Any]: 比较结果
        """
        try:
            results = {}
            
            for scenario in scenarios:
                result = objective_function(scenario.parameters)
                results[scenario.scenario_id] = {
                    'name': scenario.name,
                    'result': result,
                    'probability': scenario.probability,
                    'expected_value': result * scenario.probability,
                    'parameters': scenario.parameters
                }
            
            # 排序
            sorted_by_result = sorted(results.items(), key=lambda x: x[1]['result'], reverse=True)
            sorted_by_expected = sorted(results.items(), key=lambda x: x[1]['expected_value'], reverse=True)
            
            # 统计分析
            result_values = [r['result'] for r in results.values()]
            
            return {
                'scenario_results': results,
                'rankings': {
                    'by_result': [(item[0], item[1]['name'], item[1]['result']) for item in sorted_by_result],
                    'by_expected_value': [(item[0], item[1]['name'], item[1]['expected_value']) for item in sorted_by_expected]
                },
                'statistics': {
                    'best_scenario': sorted_by_result[0][1]['name'],
                    'worst_scenario': sorted_by_result[-1][1]['name'],
                    'result_range': max(result_values) - min(result_values),
                    'average_result': np.mean(result_values),
                    'result_variance': np.var(result_values)
                },
                'recommendations': self._generate_scenario_recommendations(sorted_by_result)
            }
            
        except Exception as e:
            self.logger.error(f"情景比较失败: {e}")
            return {'error': str(e)}
    
    def _analyze_parameter_impacts(self, base_params: Dict[str, float],
                                 new_params: Dict[str, float],
                                 base_result: float,
                                 new_result: float) -> Dict[str, Dict[str, float]]:
        """
        分析参数影响
        """
        impacts = {}
        
        for param in base_params:
            if param in new_params and base_params[param] != new_params[param]:
                param_change = new_params[param] - base_params[param]
                param_change_pct = (param_change / base_params[param] * 100) if base_params[param] != 0 else 0
                
                impacts[param] = {
                    'absolute_change': param_change,
                    'relative_change': param_change_pct,
                    'contribution_to_result': (new_result - base_result) / len([p for p in base_params if p in new_params and base_params[p] != new_params[p]])
                }
        
        return impacts
    
    def _calculate_correlations(self, parameter_samples: Dict[str, List[float]],
                              results: List[float]) -> Dict[str, float]:
        """
        计算参数与结果的相关性
        """
        correlations = {}
        
        for param, samples in parameter_samples.items():
            if len(samples) == len(results):
                correlation = np.corrcoef(samples, results)[0, 1]
                correlations[param] = correlation if not np.isnan(correlation) else 0
        
        return correlations
    
    def _generate_scenario_recommendations(self, sorted_scenarios: List[Tuple[str, Dict[str, Any]]]) -> List[str]:
        """
        生成情景建议
        """
        recommendations = []
        
        if len(sorted_scenarios) >= 1:
            best = sorted_scenarios[0][1]
            recommendations.append(f"推荐采用'{best['name']}'方案，预期结果为{best['result']:.2f}")
        
        if len(sorted_scenarios) >= 2:
            second_best = sorted_scenarios[1][1]
            recommendations.append(f"备选方案为'{second_best['name']}'，预期结果为{second_best['result']:.2f}")
        
        if len(sorted_scenarios) >= 3:
            result_range = sorted_scenarios[0][1]['result'] - sorted_scenarios[-1][1]['result']
            recommendations.append(f"各方案结果差异为{result_range:.2f}，建议重点关注前两个方案")
        
        return recommendations


class SensitivityAnalyzer:
    """
    敏感性分析器
    """
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
    
    def analyze_parameter_sensitivity(self, base_parameters: Dict[str, float],
                                    objective_function: Callable[[Dict[str, float]], float],
                                    sensitivity_range: float = 0.1,
                                    num_points: int = 11) -> Dict[str, SensitivityResult]:
        """
        分析参数敏感性
        
        Args:
            base_parameters: 基础参数
            objective_function: 目标函数
            sensitivity_range: 敏感性范围（±百分比）
            num_points: 分析点数
            
        Returns:
            Dict[str, SensitivityResult]: 敏感性结果
        """
        results = {}
        
        try:
            # 计算基础结果
            base_result = objective_function(base_parameters)
            
            for param_name, base_value in base_parameters.items():
                if base_value == 0:
                    continue  # 跳过零值参数
                
                # 生成参数变化范围
                param_range = np.linspace(
                    base_value * (1 - sensitivity_range),
                    base_value * (1 + sensitivity_range),
                    num_points
                )
                
                # 计算每个点的结果
                param_results = []
                for param_value in param_range:
                    test_params = base_parameters.copy()
                    test_params[param_name] = param_value
                    result = objective_function(test_params)
                    param_results.append(result)
                
                # 计算敏感性系数
                param_changes = param_range - base_value
                result_changes = np.array(param_results) - base_result
                
                # 线性回归计算敏感性
                if np.std(param_changes) > 0:
                    sensitivity_coeff = np.corrcoef(param_changes, result_changes)[0, 1] * (np.std(result_changes) / np.std(param_changes))
                else:
                    sensitivity_coeff = 0
                
                # 计算弹性
                elasticity = 0
                if base_value != 0 and base_result != 0:
                    # 使用中点法计算弹性
                    mid_idx = len(param_range) // 2
                    if mid_idx > 0 and mid_idx < len(param_range) - 1:
                        delta_param = (param_range[mid_idx + 1] - param_range[mid_idx - 1]) / base_value
                        delta_result = (param_results[mid_idx + 1] - param_results[mid_idx - 1]) / base_result
                        if delta_param != 0:
                            elasticity = delta_result / delta_param
                
                # 找到临界阈值（结果变化超过10%的点）
                critical_threshold = None
                for i, result in enumerate(param_results):
                    if abs(result - base_result) / abs(base_result) > 0.1:
                        critical_threshold = param_range[i]
                        break
                
                results[param_name] = SensitivityResult(
                    parameter_name=param_name,
                    base_value=base_value,
                    sensitivity_coefficient=sensitivity_coeff,
                    impact_range=(min(param_results), max(param_results)),
                    critical_threshold=critical_threshold,
                    elasticity=elasticity,
                    confidence_interval=(
                        np.percentile(param_results, 5),
                        np.percentile(param_results, 95)
                    )
                )
            
        except Exception as e:
            self.logger.error(f"敏感性分析失败: {e}")
        
        return results
    
    def analyze_cross_parameter_sensitivity(self, base_parameters: Dict[str, float],
                                          objective_function: Callable[[Dict[str, float]], float],
                                          param_pairs: List[Tuple[str, str]] = None,
                                          sensitivity_range: float = 0.1,
                                          grid_size: int = 5) -> Dict[str, Dict[str, Any]]:
        """
        分析参数交互敏感性
        
        Args:
            base_parameters: 基础参数
            objective_function: 目标函数
            param_pairs: 参数对列表
            sensitivity_range: 敏感性范围
            grid_size: 网格大小
            
        Returns:
            Dict[str, Dict[str, Any]]: 交互敏感性结果
        """
        if param_pairs is None:
            # 自动生成参数对
            param_names = list(base_parameters.keys())
            param_pairs = [(param_names[i], param_names[j]) 
                          for i in range(len(param_names)) 
                          for j in range(i+1, len(param_names))]
        
        results = {}
        
        try:
            base_result = objective_function(base_parameters)
            
            for param1, param2 in param_pairs:
                if param1 not in base_parameters or param2 not in base_parameters:
                    continue
                
                base_val1 = base_parameters[param1]
                base_val2 = base_parameters[param2]
                
                if base_val1 == 0 or base_val2 == 0:
                    continue
                
                # 创建参数网格
                param1_range = np.linspace(
                    base_val1 * (1 - sensitivity_range),
                    base_val1 * (1 + sensitivity_range),
                    grid_size
                )
                param2_range = np.linspace(
                    base_val2 * (1 - sensitivity_range),
                    base_val2 * (1 + sensitivity_range),
                    grid_size
                )
                
                # 计算网格结果
                grid_results = np.zeros((grid_size, grid_size))
                for i, val1 in enumerate(param1_range):
                    for j, val2 in enumerate(param2_range):
                        test_params = base_parameters.copy()
                        test_params[param1] = val1
                        test_params[param2] = val2
                        grid_results[i, j] = objective_function(test_params)
                
                # 分析交互效应
                interaction_strength = np.std(grid_results) / abs(base_result) if base_result != 0 else 0
                
                # 找到最优组合
                max_idx = np.unravel_index(np.argmax(grid_results), grid_results.shape)
                optimal_combination = {
                    param1: param1_range[max_idx[0]],
                    param2: param2_range[max_idx[1]],
                    'result': grid_results[max_idx]
                }
                
                results[f"{param1}_{param2}"] = {
                    'param1': param1,
                    'param2': param2,
                    'interaction_strength': interaction_strength,
                    'optimal_combination': optimal_combination,
                    'result_range': (np.min(grid_results), np.max(grid_results)),
                    'grid_results': grid_results.tolist(),
                    'param1_range': param1_range.tolist(),
                    'param2_range': param2_range.tolist()
                }
            
        except Exception as e:
            self.logger.error(f"交互敏感性分析失败: {e}")
        
        return results
    
    def generate_sensitivity_report(self, sensitivity_results: Dict[str, SensitivityResult],
                                  cross_sensitivity_results: Dict[str, Dict[str, Any]] = None) -> Dict[str, Any]:
        """
        生成敏感性分析报告
        
        Args:
            sensitivity_results: 单参数敏感性结果
            cross_sensitivity_results: 交互敏感性结果
            
        Returns:
            Dict[str, Any]: 敏感性报告
        """
        try:
            # 排序参数敏感性
            sorted_params = sorted(
                sensitivity_results.items(),
                key=lambda x: abs(x[1].sensitivity_coefficient),
                reverse=True
            )
            
            # 识别高敏感性参数
            high_sensitivity_params = [
                (name, result) for name, result in sorted_params
                if abs(result.sensitivity_coefficient) > 0.5
            ]
            
            # 识别低敏感性参数
            low_sensitivity_params = [
                (name, result) for name, result in sorted_params
                if abs(result.sensitivity_coefficient) < 0.1
            ]
            
            # 生成建议
            recommendations = []
            
            if high_sensitivity_params:
                recommendations.append(
                    f"高敏感性参数：{', '.join([name for name, _ in high_sensitivity_params[:3]])}，需要重点监控"
                )
            
            if low_sensitivity_params:
                recommendations.append(
                    f"低敏感性参数：{', '.join([name for name, _ in low_sensitivity_params[:3]])}，可以适当放宽控制"
                )
            
            # 交互效应分析
            interaction_summary = {}
            if cross_sensitivity_results:
                strong_interactions = [
                    (pair, data) for pair, data in cross_sensitivity_results.items()
                    if data['interaction_strength'] > 0.2
                ]
                
                if strong_interactions:
                    interaction_summary = {
                        'strong_interactions': strong_interactions,
                        'recommendations': [
                            f"参数对{pair}存在强交互效应，需要同时优化"
                            for pair, _ in strong_interactions[:3]
                        ]
                    }
            
            return {
                'summary': {
                    'total_parameters': len(sensitivity_results),
                    'high_sensitivity_count': len(high_sensitivity_params),
                    'low_sensitivity_count': len(low_sensitivity_params),
                    'most_sensitive_parameter': sorted_params[0][0] if sorted_params else None,
                    'least_sensitive_parameter': sorted_params[-1][0] if sorted_params else None
                },
                'parameter_rankings': [
                    {
                        'parameter': name,
                        'sensitivity_coefficient': result.sensitivity_coefficient,
                        'elasticity': result.elasticity,
                        'critical_threshold': result.critical_threshold
                    }
                    for name, result in sorted_params
                ],
                'high_sensitivity_parameters': [
                    {
                        'parameter': name,
                        'sensitivity_coefficient': result.sensitivity_coefficient,
                        'impact_range': result.impact_range
                    }
                    for name, result in high_sensitivity_params
                ],
                'interaction_analysis': interaction_summary,
                'recommendations': recommendations,
                'analysis_metadata': {
                    'analysis_date': datetime.now().isoformat(),
                    'analysis_type': 'sensitivity_analysis'
                }
            }
            
        except Exception as e:
            self.logger.error(f"敏感性报告生成失败: {e}")
            return {'error': str(e)}


class InteractiveDecisionSupportSystem:
    """
    交互式决策支持系统
    """
    
    def __init__(self, max_workers: int = 4):
        self.logger = logging.getLogger(__name__)
        self.decision_engine = RealTimeDecisionEngine(max_workers)
        self.scenario_simulator = ScenarioSimulator()
        self.sensitivity_analyzer = SensitivityAnalyzer()
        
        # 系统状态
        self.system_metrics = defaultdict(list)
        self.user_sessions = {}
    
    def start_interactive_session(self, user_id: str, problem_description: str,
                                objectives: List[str] = None,
                                constraints: Dict[str, Any] = None,
                                preferences: Dict[str, Any] = None) -> str:
        """
        启动交互式决策会话
        
        Args:
            user_id: 用户ID
            problem_description: 问题描述
            objectives: 目标列表
            constraints: 约束条件
            preferences: 用户偏好
            
        Returns:
            str: 会话ID
        """
        try:
            # 创建决策上下文
            context = DecisionContext(
                user_id=user_id,
                session_id="",  # 将由引擎生成
                problem_type=self._classify_problem_type(problem_description),
                urgency=self._assess_urgency(problem_description),
                objectives=objectives or [],
                constraints=constraints or {},
                preferences=preferences or {}
            )
            
            # 创建会话
            session_id = self.decision_engine.create_session(user_id, context)
            context.session_id = session_id
            
            # 记录会话
            self.user_sessions[session_id] = {
                'start_time': datetime.now(),
                'user_id': user_id,
                'problem_description': problem_description,
                'status': 'active'
            }
            
            self.logger.info(f"启动交互式决策会话: {session_id}")
            return session_id
            
        except Exception as e:
            self.logger.error(f"启动交互式会话失败: {e}")
            raise
    
    def get_interactive_recommendation(self, session_id: str,
                                     current_data: Dict[str, Any],
                                     analysis_type: AnalysisType = AnalysisType.OPTIMIZATION) -> Dict[str, Any]:
        """
        获取交互式建议
        
        Args:
            session_id: 会话ID
            current_data: 当前数据
            analysis_type: 分析类型
            
        Returns:
            Dict[str, Any]: 建议结果
        """
        try:
            start_time = time.time()
            
            # 获取实时建议
            recommendation = self.decision_engine.get_real_time_recommendation(
                session_id, current_data, analysis_type
            )
            
            # 如果需要，运行额外分析
            additional_analysis = {}
            
            if analysis_type == AnalysisType.SENSITIVITY:
                # 运行敏感性分析
                if 'parameters' in current_data and 'objective_function' in current_data:
                    sensitivity_results = self.sensitivity_analyzer.analyze_parameter_sensitivity(
                        current_data['parameters'],
                        current_data['objective_function']
                    )
                    additional_analysis['sensitivity'] = sensitivity_results
            
            elif analysis_type == AnalysisType.WHAT_IF:
                # 运行假设分析
                if 'base_scenario' in current_data and 'parameter_changes' in current_data:
                    what_if_results = self.scenario_simulator.run_what_if_analysis(
                        current_data['base_scenario'],
                        current_data['parameter_changes'],
                        current_data.get('objective_function', lambda x: sum(x.values()))
                    )
                    additional_analysis['what_if'] = what_if_results
            
            processing_time = time.time() - start_time
            self.system_metrics['response_time'].append(processing_time)
            
            return {
                'recommendation': self._recommendation_to_dict(recommendation),
                'additional_analysis': additional_analysis,
                'metadata': {
                    'session_id': session_id,
                    'analysis_type': analysis_type.value,
                    'processing_time': processing_time,
                    'timestamp': datetime.now().isoformat()
                }
            }
            
        except Exception as e:
            self.logger.error(f"获取交互式建议失败: {e}")
            return {'error': str(e)}
    
    def run_comprehensive_analysis(self, session_id: str,
                                 scenarios: List[Dict[str, Any]],
                                 objective_function: Callable[[Dict[str, float]], float]) -> Dict[str, Any]:
        """
        运行综合分析
        
        Args:
            session_id: 会话ID
            scenarios: 情景列表
            objective_function: 目标函数
            
        Returns:
            Dict[str, Any]: 综合分析结果
        """
        try:
            # 创建情景参数
            scenario_params = []
            for i, scenario_data in enumerate(scenarios):
                scenario = self.scenario_simulator.create_scenario(
                    name=scenario_data.get('name', f'Scenario_{i+1}'),
                    description=scenario_data.get('description', ''),
                    parameters=scenario_data.get('parameters', {}),
                    probability=scenario_data.get('probability', 1.0)
                )
                scenario_params.append(scenario)
            
            # 情景比较
            scenario_comparison = self.scenario_simulator.compare_scenarios(
                scenario_params, objective_function
            )
            
            # 敏感性分析（使用最佳情景）
            best_scenario = scenario_params[0] if scenario_params else None
            sensitivity_results = {}
            
            if best_scenario:
                sensitivity_results = self.sensitivity_analyzer.analyze_parameter_sensitivity(
                    best_scenario.parameters, objective_function
                )
            
            # 蒙特卡洛模拟（如果提供了参数分布）
            monte_carlo_results = {}
            if scenarios and 'parameter_distributions' in scenarios[0]:
                monte_carlo_results = self.scenario_simulator.run_monte_carlo_simulation(
                    best_scenario,
                    scenarios[0]['parameter_distributions'],
                    objective_function
                )
            
            # 生成综合建议
            comprehensive_recommendation = self._generate_comprehensive_recommendation(
                scenario_comparison, sensitivity_results, monte_carlo_results
            )
            
            return {
                'scenario_analysis': scenario_comparison,
                'sensitivity_analysis': self.sensitivity_analyzer.generate_sensitivity_report(sensitivity_results),
                'monte_carlo_simulation': monte_carlo_results,
                'comprehensive_recommendation': comprehensive_recommendation,
                'metadata': {
                    'session_id': session_id,
                    'analysis_date': datetime.now().isoformat(),
                    'scenarios_analyzed': len(scenarios)
                }
            }
            
        except Exception as e:
            self.logger.error(f"综合分析失败: {e}")
            return {'error': str(e)}
    
    def update_session_feedback(self, session_id: str, recommendation_id: str,
                              feedback_type: str, feedback_data: Dict[str, Any]):
        """
        更新会话反馈
        
        Args:
            session_id: 会话ID
            recommendation_id: 建议ID
            feedback_type: 反馈类型
            feedback_data: 反馈数据
        """
        try:
            feedback = {
                'type': feedback_type,
                'data': feedback_data,
                'timestamp': datetime.now().isoformat()
            }
            
            self.decision_engine.update_user_feedback(
                session_id, recommendation_id, feedback
            )
            
            # 更新系统学习
            self._update_system_learning(session_id, feedback)
            
        except Exception as e:
            self.logger.error(f"更新会话反馈失败: {e}")
    
    def close_interactive_session(self, session_id: str) -> Dict[str, Any]:
        """
        关闭交互式会话
        
        Args:
            session_id: 会话ID
            
        Returns:
            Dict[str, Any]: 会话总结
        """
        try:
            # 生成会话总结
            session_summary = self._generate_session_summary(session_id)
            
            # 关闭引擎会话
            self.decision_engine.close_session(session_id)
            
            # 更新会话状态
            if session_id in self.user_sessions:
                self.user_sessions[session_id]['status'] = 'closed'
                self.user_sessions[session_id]['end_time'] = datetime.now()
            
            self.logger.info(f"关闭交互式决策会话: {session_id}")
            return session_summary
            
        except Exception as e:
            self.logger.error(f"关闭交互式会话失败: {e}")
            return {'error': str(e)}
    
    def get_system_status(self) -> Dict[str, Any]:
        """
        获取系统状态
        
        Returns:
            Dict[str, Any]: 系统状态
        """
        engine_metrics = self.decision_engine.get_performance_metrics()
        
        return {
            'active_sessions': len([s for s in self.user_sessions.values() if s['status'] == 'active']),
            'total_sessions': len(self.user_sessions),
            'engine_metrics': engine_metrics,
            'system_metrics': {
                'avg_response_time': np.mean(self.system_metrics['response_time']) if self.system_metrics['response_time'] else 0,
                'total_analyses': len(self.system_metrics['response_time'])
            },
            'uptime': datetime.now().isoformat()
        }
    
    # 辅助方法
    def _classify_problem_type(self, description: str) -> str:
        """
        分类问题类型
        """
        keywords = {
            '优化': ['优化', '最大化', '最小化', '最优'],
            '决策': ['选择', '决策', '方案', '策略'],
            '风险': ['风险', '不确定', '概率', '随机'],
            '资源': ['资源', '分配', '调度', '配置']
        }
        
        for problem_type, words in keywords.items():
            if any(word in description for word in words):
                return problem_type
        
        return '通用决策'
    
    def _assess_urgency(self, description: str) -> DecisionUrgency:
        """
        评估紧急程度
        """
        urgent_keywords = ['紧急', '立即', '马上', '急需']
        high_keywords = ['重要', '关键', '核心', '优先']
        
        if any(word in description for word in urgent_keywords):
            return DecisionUrgency.CRITICAL
        elif any(word in description for word in high_keywords):
            return DecisionUrgency.HIGH
        else:
            return DecisionUrgency.MEDIUM
    
    def _recommendation_to_dict(self, recommendation: DecisionRecommendation) -> Dict[str, Any]:
        """
        将建议对象转换为字典
        """
        return {
            'recommendation_id': recommendation.recommendation_id,
            'title': recommendation.title,
            'description': recommendation.description,
            'recommended_action': recommendation.recommended_action,
            'confidence': recommendation.confidence.value,
            'expected_outcome': recommendation.expected_outcome,
            'implementation_steps': recommendation.implementation_steps,
            'required_resources': recommendation.required_resources,
            'timeline': recommendation.timeline,
            'risks': recommendation.risks,
            'alternatives': recommendation.alternatives,
            'success_probability': recommendation.success_probability,
            'cost_benefit_ratio': recommendation.cost_benefit_ratio,
            'stakeholder_impact': recommendation.stakeholder_impact
        }
    
    def _generate_comprehensive_recommendation(self, scenario_analysis: Dict[str, Any],
                                             sensitivity_analysis: Dict[str, Any],
                                             monte_carlo_results: Dict[str, Any]) -> Dict[str, Any]:
        """
        生成综合建议
        """
        recommendations = []
        
        # 基于情景分析的建议
        if 'statistics' in scenario_analysis:
            best_scenario = scenario_analysis['statistics'].get('best_scenario')
            if best_scenario:
                recommendations.append(f"推荐采用'{best_scenario}'情景方案")
        
        # 基于敏感性分析的建议
        if 'high_sensitivity_parameters' in sensitivity_analysis:
            high_params = sensitivity_analysis['high_sensitivity_parameters']
            if high_params:
                param_names = [p['parameter'] for p in high_params[:2]]
                recommendations.append(f"重点监控参数：{', '.join(param_names)}")
        
        # 基于蒙特卡洛模拟的建议
        if 'risk_metrics' in monte_carlo_results:
            risk_metrics = monte_carlo_results['risk_metrics']
            if risk_metrics.get('probability_of_loss', 0) > 0.1:
                recommendations.append("存在较高风险，建议制定风险缓解措施")
        
        return {
            'summary': '基于多维度分析的综合决策建议',
            'key_recommendations': recommendations,
            'confidence_level': 'HIGH',
            'analysis_completeness': {
                'scenario_analysis': bool(scenario_analysis),
                'sensitivity_analysis': bool(sensitivity_analysis),
                'monte_carlo_simulation': bool(monte_carlo_results)
            }
        }
    
    def _update_system_learning(self, session_id: str, feedback: Dict[str, Any]):
        """
        更新系统学习
        """
        # 记录反馈用于系统改进
        self.system_metrics['user_feedback'].append({
            'session_id': session_id,
            'feedback': feedback,
            'timestamp': datetime.now()
        })
    
    def _generate_session_summary(self, session_id: str) -> Dict[str, Any]:
        """
        生成会话总结
        """
        session_info = self.user_sessions.get(session_id, {})
        
        if not session_info:
            return {'error': '会话不存在'}
        
        # 获取会话详情
        session = self.decision_engine.active_sessions.get(session_id)
        
        if session:
            duration = datetime.now() - session.start_time
            
            return {
                'session_id': session_id,
                'user_id': session.user_id,
                'duration': str(duration),
                'total_recommendations': len(session.recommendations),
                'total_analyses': len(session.analysis_history),
                'user_feedback_count': len(session.user_feedback),
                'problem_type': session.context.problem_type,
                'final_status': 'completed'
            }
        else:
            return {
                'session_id': session_id,
                'status': 'session_data_unavailable'
            }